// Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved.

// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <tests/tools/TestTools.h>

#include <training/base/layers/basic/DataLayer.h>
#include <training/base/layers/basic/DynamicDepthwiseConvolution2DLayer.h>
#include <training/base/layers/basic/TensorLayer.h>
#include <training/compiler/Workflow.h>

namespace UT
{

TEST(TestLayerDynamicDepthwiseConvolution2D, BatchedUnit)
{
    PROFILE_TEST

    // see tf_depthwise_conv2d.py
    // Test settings
    constexpr raul::dtype eps = 1.0e-6_dt;

    // Inputs
    const raul::Tensor input{
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0.01975703_dt, 0.00704217_dt, 0.18987215_dt, 0.7772658_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0.41817415_dt, 0.7437942_dt,  0.26365364_dt, 0.4459244_dt,  0._dt, 0._dt,
        0._dt, 0._dt, 0.82929873_dt, 0.52497685_dt, 0.55597556_dt, 0.19923508_dt, 0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0.46925998_dt, 0.18594062_dt, 0.23303056_dt, 0.3938471_dt,  0._dt, 0._dt,
        0._dt, 0._dt, 0.9660922_dt,  0.36530995_dt, 0.28173566_dt, 0.4888971_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0.96301997_dt, 0.45836866_dt, 0.70952535_dt, 0.477888_dt,   0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0.71620464_dt, 0.12221897_dt, 0.2998824_dt,  0.6689563_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0.06436884_dt, 0.23358119_dt, 0.8235085_dt,  0.24635303_dt, 0._dt, 0._dt,
        0._dt, 0._dt, 0.87422705_dt, 0.97360873_dt, 0.5011089_dt,  0.4178022_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0.19041097_dt, 0.05045938_dt, 0.07118928_dt, 0.17497218_dt, 0._dt, 0._dt,
        0._dt, 0._dt, 0.06644797_dt, 0.7329292_dt,  0.8574884_dt,  0.4593867_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0.28661895_dt, 0.7181833_dt,  0.30093706_dt, 0.02433372_dt, 0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0.42253482_dt, 0.06825948_dt, 0.48981392_dt, 0.92883205_dt, 0._dt, 0._dt, 0._dt, 0._dt, 0.9339298_dt,  0.41831005_dt, 0.8322693_dt,  0.22140837_dt, 0._dt, 0._dt,
        0._dt, 0._dt, 0.23945987_dt, 0.7574657_dt,  0.5762696_dt,  0.5139812_dt,  0._dt, 0._dt, 0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt,
        0._dt, 0._dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt, 0._dt
    };

    const raul::Tensor filters{ 0.77896154_dt, 0.5083395_dt,  0.37192822_dt, 0.2564721_dt,  0.0173713_dt,  0.12236476_dt, 0.41399598_dt, 0.6549072_dt,  0.58900976_dt, 0.41211855_dt,
                                0.904863_dt,   0.383209_dt,   0.32986057_dt, 0.66525745_dt, 0.8445356_dt,  0.5856713_dt,  0.7861192_dt,  0.17401242_dt, 0.45946157_dt, 0.455971_dt,
                                0.5607773_dt,  0.36806154_dt, 0.71749187_dt, 0.05388129_dt, 0.34521234_dt, 0.24467218_dt, 0.5839158_dt,  0.09249318_dt, 0.4646201_dt,  0.26813436_dt,
                                0.91642344_dt, 0.12303817_dt, 0.6001576_dt,  0.7009108_dt,  0.3092351_dt,  0.06028998_dt, 0.625105_dt,   0.36331964_dt, 0.15423799_dt, 0.12976074_dt,
                                0.4372971_dt,  0.14352834_dt, 0.05433822_dt, 0.17287242_dt, 0.73136127_dt, 0.62641513_dt, 0.49098003_dt, 0.42000008_dt, 0.2128079_dt,  0.38877666_dt,
                                0.7380631_dt,  0.44847226_dt, 0.222965_dt,   0.4715277_dt,  0.01670182_dt, 0.5786401_dt,  0.05703926_dt, 0.6873926_dt,  0.17311347_dt, 0.26997936_dt,
                                0.36309445_dt, 0.6264982_dt,  0.5275842_dt,  0.7112013_dt,  0.4725076_dt,  0.15004325_dt, 0.7902857_dt,  0.6516645_dt,  0.85346174_dt, 0.3106085_dt,
                                0.2373141_dt,  0.9790237_dt,  0.37913144_dt, 0.856442_dt,   0.32877612_dt, 0.19255197_dt, 0.51858544_dt, 0.20067143_dt, 0.63354146_dt, 0.99083376_dt,
                                0.54786384_dt, 0.58600605_dt, 0.49146748_dt, 0.6517689_dt,  0.58926547_dt, 0.7655344_dt,  0.9426141_dt,  0.4075675_dt,  0.7852074_dt,  0.7942022_dt };

    const raul::Tensor realFeatures{
        1.2546906_dt,  1.758348_dt,   1.5786406_dt, 1.4093302_dt,  1.0484831_dt, 1.4180284_dt,  0.79202974_dt, 1.7082783_dt,  0.8821168_dt,  1.5340638_dt,  1.0943279_dt, 0.8303825_dt,
        1.0001473_dt,  1.0848525_dt,  1.5379478_dt, 1.6466024_dt,  1.0035802_dt, 0.84523404_dt, 0.56607544_dt, 1.0811576_dt,  0.71989954_dt, 0.9528942_dt,  1.0954056_dt, 0.6744617_dt,
        0.6201665_dt,  0.63352114_dt, 1.5912652_dt, 1.2576785_dt,  1.4030486_dt, 0.67870927_dt, 0.9257573_dt,  0.78698933_dt, 1.0421672_dt,  0.83006406_dt, 1.7716845_dt, 0.61738896_dt,
        1.6767358_dt,  2.45793_dt,    2.4617476_dt, 1.1681485_dt,  1.0682555_dt, 1.4755492_dt,  1.2390563_dt,  2.4740949_dt,  1.1518929_dt,  1.2379603_dt,  1.0414997_dt, 0.76753944_dt,
        1.3983952_dt,  1.4857323_dt,  2.4419913_dt, 1.215771_dt,   0.8265422_dt, 0.99419963_dt, 1.188979_dt,   1.6724479_dt,  1.1835436_dt,  1.113475_dt,   1.0213432_dt, 0.56884575_dt,
        1.0661569_dt,  1.1757137_dt,  2.4343936_dt, 1.185205_dt,   1.1303781_dt, 0.6850685_dt,  1.6436929_dt,  1.3731412_dt,  1.6855145_dt,  0.7485111_dt,  1.2839427_dt, 0.5909537_dt,
        1.6260588_dt,  2.0672073_dt,  2.4332392_dt, 1.360034_dt,   1.1845512_dt, 1.6093835_dt,  1.413005_dt,   2.110466_dt,   1.3298943_dt,  1.2029771_dt,  1.2489654_dt, 0.8662152_dt,
        1.4142549_dt,  1.4176774_dt,  2.1419637_dt, 1.5591891_dt,  0.9924498_dt, 0.84249055_dt, 0.7141279_dt,  1.3854965_dt,  1.50319_dt,    1.2578799_dt,  0.9875599_dt, 0.6484919_dt,
        1.3264725_dt,  1.1315681_dt,  2.2161596_dt, 1.4336894_dt,  1.392356_dt,  0.8466469_dt,  1.5696193_dt,  1.1955621_dt,  1.4612973_dt,  0.8038471_dt,  1.5203788_dt, 0.6651642_dt,
        1.0862007_dt,  1.1753873_dt,  1.3993876_dt, 1.2048057_dt,  0.8911915_dt, 1.1508342_dt,  0.7346766_dt,  1.2008022_dt,  0.7967271_dt,  1.0992267_dt,  0.8363159_dt, 0.50751317_dt,
        0.65895873_dt, 0.775882_dt,   1.2434406_dt, 1.3107783_dt,  0.8849546_dt, 0.6801046_dt,  0.31424892_dt, 0.6310036_dt,  0.9608475_dt,  0.9286081_dt,  0.7993823_dt, 0.54531914_dt,
        0.99068916_dt, 0.4603683_dt,  1.1574365_dt, 0.97384536_dt, 1.0238392_dt, 0.5871148_dt,  0.69986004_dt, 0.5396757_dt,  0.9150152_dt,  0.50573885_dt, 1.2245203_dt, 0.34919372_dt,
        1.6153148_dt,  2.0693576_dt,  2.5479672_dt, 1.4789497_dt,  1.2666607_dt, 1.6480653_dt,  1.0644124_dt,  2.0760858_dt,  1.3102106_dt,  1.4827486_dt,  1.3083357_dt, 1.0330613_dt,
        1.3649669_dt,  1.1742215_dt,  2.456157_dt,  1.7170308_dt,  1.0535737_dt, 0.9712448_dt,  1.2054962_dt,  1.2952919_dt,  1.5933845_dt,  1.1902285_dt,  1.1461501_dt, 0.6873801_dt,
        1.5572598_dt,  1.1989173_dt,  2.3078265_dt, 1.4709939_dt,  1.5412611_dt, 0.87378997_dt, 1.4293349_dt,  1.3516736_dt,  1.9137547_dt,  0.9949931_dt,  1.8282485_dt, 0.77078557_dt
    };

    const raul::Tensor deltas{ 0.2455703_dt,  0.67252374_dt, 0.06595552_dt, 0.22566724_dt, 0.12165248_dt, 0.34891522_dt, 0.11888039_dt, 0.47397935_dt, 0.8101833_dt,  0.08105242_dt, 0.14795518_dt,
                               0.8522136_dt,  0.88956475_dt, 0.5235504_dt,  0.78217006_dt, 0.0097661_dt,  0.9842837_dt,  0.4528315_dt,  0.1684258_dt,  0.09325731_dt, 0.5867677_dt,  0.47904193_dt,
                               0.90361214_dt, 0.44907594_dt, 0.6200323_dt,  0.34236217_dt, 0.9900886_dt,  0.18420243_dt, 0.4838239_dt,  0.4779688_dt,  0.7693052_dt,  0.7986605_dt,  0.8320849_dt,
                               0.0491637_dt,  0.20643818_dt, 0.61298096_dt, 0.22808123_dt, 0.76741135_dt, 0.886292_dt,   0.33155513_dt, 0.51319087_dt, 0.15767169_dt, 0.13007402_dt, 0.9465703_dt,
                               0.18995786_dt, 0.36849797_dt, 0.9293808_dt,  0.5779208_dt,  0.20169926_dt, 0.2623061_dt,  0.0521735_dt,  0.64536107_dt, 0.5865052_dt,  0.5442966_dt,  0.6695279_dt,
                               0.6453804_dt,  0.18496847_dt, 0.68037975_dt, 0.2035402_dt,  0.37345743_dt, 0.48308456_dt, 0.47415805_dt, 0.7709352_dt,  0.02728796_dt, 0.26876915_dt, 0.3912257_dt,
                               0.47889543_dt, 0.36939442_dt, 0.56657505_dt, 0.09261692_dt, 0.69726706_dt, 0.7697934_dt,  0.37017977_dt, 0.72821045_dt, 0.5914197_dt,  0.13103616_dt, 0.8721162_dt,
                               0.9396914_dt,  0.0898335_dt,  0.64125204_dt, 0.59468186_dt, 0.9526489_dt,  0.58091915_dt, 0.41282332_dt, 0.08863175_dt, 0.8548584_dt,  0.4440868_dt,  0.70558417_dt,
                               0.55628467_dt, 0.7936231_dt,  0.03845227_dt, 0.72081244_dt, 0.7246641_dt,  0.77859426_dt, 0.13219965_dt, 0.7014549_dt,  0.00531662_dt, 0.16521204_dt, 0.31161308_dt,
                               0.6340182_dt,  0.81727743_dt, 0.5770134_dt,  0.4830289_dt,  0.38074362_dt, 0.36956656_dt, 0.35619748_dt, 0.9744946_dt,  0.4673227_dt,  0.02055061_dt, 0.01841414_dt,
                               0.38048124_dt, 0.19153368_dt, 0.24953306_dt, 0.04886508_dt, 0.8518716_dt,  0.2697699_dt,  0.43472767_dt, 0.6233506_dt,  0.7728535_dt,  0.7977462_dt,  0.17800307_dt,
                               0.39288294_dt, 0.74178994_dt, 0.5404706_dt,  0.6666156_dt,  0.5245379_dt,  0.5809839_dt,  0.5353533_dt,  0.24594212_dt, 0.47274435_dt, 0.8491398_dt,  0.24667323_dt,
                               0.2283063_dt,  0.4228245_dt,  0.7832608_dt,  0.27312124_dt, 0.50172055_dt, 0.33225644_dt, 0.4334905_dt,  0.55062807_dt, 0.8973236_dt,  0.89052856_dt, 0.04011297_dt,
                               0.09300995_dt, 0.86229265_dt, 0.1463412_dt,  0.6064124_dt,  0.77159905_dt, 0.11275506_dt, 0.7820941_dt,  0.03212047_dt, 0.5106342_dt,  0.24657166_dt, 0.6957668_dt,
                               0.18525338_dt, 0.9630281_dt,  0.7088288_dt,  0.9751494_dt,  0.06359577_dt, 0.03091824_dt, 0.7603164_dt,  0.2684846_dt,  0.38360918_dt, 0.4091003_dt,  0.8824315_dt,
                               0.23227227_dt, 0.35561895_dt, 0.47684944_dt, 0.16890907_dt, 0.02330649_dt, 0.07008195_dt, 0.5172961_dt,  0.98326766_dt, 0.8809185_dt,  0.27750802_dt, 0.37777352_dt,
                               0.4160868_dt,  0.37960744_dt, 0.00660408_dt, 0.87966454_dt };

    const raul::Tensor realInputGrad{
        0.5576909_dt,  0.10268554_dt, 1.21583_dt,    0.4644267_dt,  1.4209416_dt,  0.7823741_dt,  1.0387609_dt, 0.31207624_dt, 1.7064569_dt,  0.26415774_dt, 2.5816064_dt, 1.614563_dt,
        2.7561765_dt,  2.567015_dt,   1.2666433_dt,  1.2229962_dt,  2.5193486_dt,  0.98090345_dt, 4.2689877_dt, 2.7617307_dt,  5.41607_dt,    2.7106342_dt,  2.8133173_dt, 1.411195_dt,
        2.260148_dt,   1.2077585_dt,  3.868504_dt,   2.3523033_dt,  5.032123_dt,   2.6380591_dt,  2.9021127_dt, 1.6579413_dt,  1.7178662_dt,  0.77999735_dt, 4.4457464_dt, 2.5680385_dt,
        5.6356497_dt,  3.4607222_dt,  2.9795966_dt,  1.9860446_dt,  1.3077455_dt,  0.9426035_dt,  3.3319125_dt, 2.101921_dt,   4.9596415_dt,  3.0184565_dt,  2.562317_dt,  1.925806_dt,
        0.8538045_dt,  0.38228726_dt, 2.5237176_dt,  0.8967829_dt,  3.295321_dt,   1.3643707_dt,  1.849062_dt,  0.66896516_dt, 0.897409_dt,   0.11324289_dt, 1.7721951_dt, 0.8427998_dt,
        2.119919_dt,   1.8393399_dt,  0.83304536_dt, 1.0469882_dt,  1.2615857_dt,  0.7410467_dt,  2.5863404_dt, 2.3739586_dt,  2.316667_dt,   2.5628784_dt,  1.1560793_dt, 1.2039962_dt,
        1.703695_dt,   1.0372825_dt,  3.8538268_dt,  2.4922085_dt,  3.955898_dt,   3.450927_dt,   2.2220776_dt, 1.943661_dt,   1.5983331_dt,  1.0016215_dt,  3.8070493_dt, 3.032041_dt,
        4.1941357_dt,  3.1916635_dt,  2.2360268_dt,  1.7543677_dt,  1.7863901_dt,  1.2309372_dt,  4.166173_dt,  3.3804798_dt,  5.1619616_dt,  4.201617_dt,   2.751583_dt,  2.52417_dt,
        0.6446827_dt,  0.7085514_dt,  2.4169133_dt,  1.9299953_dt,  3.5867696_dt,  2.8640993_dt,  2.16568_dt,   1.6816076_dt,  0.84270644_dt, 0.22314194_dt, 1.882439_dt,  0.9369726_dt,
        2.3541582_dt,  1.4315591_dt,  1.0990422_dt,  1.1966186_dt,  0.8784996_dt,  0.16374204_dt, 1.5956448_dt, 1.5081806_dt,  1.9134548_dt,  2.0023036_dt,  0.9584602_dt, 1.0864471_dt,
        1.5025485_dt,  1.0123351_dt,  2.8424652_dt,  2.8450546_dt,  3.2067394_dt,  2.5848465_dt,  1.6223412_dt, 1.5542384_dt,  1.470764_dt,   1.4822503_dt,  3.2123826_dt, 3.6849844_dt,
        3.456596_dt,   5.1094837_dt,  1.9909093_dt,  2.436319_dt,   1.1482949_dt,  1.7943096_dt,  3.011209_dt,  4.2696443_dt,  4.043538_dt,   5.1864557_dt,  2.5309825_dt, 2.1265197_dt,
        1.5913383_dt,  1.9841243_dt,  4.073986_dt,   4.896811_dt,   4.8628902_dt,  6.083433_dt,   2.746561_dt,  2.7296062_dt,  1.0252061_dt,  1.316683_dt,   2.5359368_dt, 3.0267444_dt,
        3.2475493_dt,  4.072784_dt,   2.2028027_dt,  1.7776501_dt,  0.24596116_dt, 0.6616998_dt,  0.9685084_dt, 1.8170067_dt,  1.3090839_dt,  2.3506553_dt,  0.9244632_dt, 1.2815036_dt,
        0.16688047_dt, 0.05943713_dt, 1.207072_dt,   0.59436685_dt, 1.1257634_dt,  1.5787661_dt,  0.8276083_dt, 1.1114513_dt,  0.84547186_dt, 0.4665476_dt,  2.576058_dt,  2.1668088_dt,
        2.54592_dt,    2.8345635_dt,  1.8302705_dt,  1.7113249_dt,  1.4392259_dt,  0.9658877_dt,  4.0039215_dt, 3.0276153_dt,  3.9217286_dt,  3.4416733_dt,  2.6200447_dt, 2.006117_dt,
        1.1380541_dt,  1.1033841_dt,  3.2236466_dt,  3.102367_dt,   3.6424043_dt,  3.0423124_dt,  2.7368813_dt, 2.3178868_dt,  0.8384216_dt,  1.1071498_dt,  3.240076_dt,  2.967668_dt,
        4.70199_dt,    4.199554_dt,   3.1047962_dt,  2.5365076_dt,  0.9410038_dt,  0.91932404_dt, 2.8061519_dt, 2.6924577_dt,  4.2383738_dt,  3.2108688_dt,  2.451251_dt,  1.4325186_dt,
        0.70620024_dt, 0.3794494_dt,  1.9236599_dt,  0.83412397_dt, 2.5083585_dt,  1.3713393_dt,  1.5227956_dt, 0.4683162_dt,  0.9716257_dt,  0.2955531_dt,  1.1863115_dt, 1.0192273_dt,
        1.3868766_dt,  1.5000448_dt,  0.558537_dt,   0.72070074_dt, 1.8744905_dt,  0.46102738_dt, 2.8779607_dt, 1.7020626_dt,  3.3349226_dt,  2.2942593_dt,  1.3841847_dt, 1.1015902_dt,
        1.6611931_dt,  1.0905963_dt,  2.826785_dt,   3.6167417_dt,  3.2516243_dt,  3.9875083_dt,  2.0130806_dt, 1.4895421_dt,  1.068397_dt,   2.0794399_dt,  2.450947_dt,  3.1819956_dt,
        3.7007842_dt,  3.5831351_dt,  2.0110729_dt,  1.9323556_dt,  1.3562186_dt,  1.2128909_dt,  3.1887813_dt, 3.5673032_dt,  4.4456472_dt,  4.485358_dt,   2.47816_dt,   2.4037614_dt,
        1.1451116_dt,  1.2177517_dt,  2.5959253_dt,  2.355865_dt,   3.1214237_dt,  3.1060677_dt,  2.1916268_dt, 1.7333051_dt,  0.10704067_dt, 0.7862899_dt,  0.7340517_dt, 1.6135805_dt,
        0.96151686_dt, 2.4815655_dt,  0.84493375_dt, 0.8585328_dt
    };

    const raul::Tensor realFiltersGrad{ 0.78567135_dt, 0.7262797_dt, 0.8936672_dt,  0.13194889_dt, 0.25268063_dt, 0.26930696_dt, 0.92689794_dt, 1.0140908_dt, 1.451793_dt,   0.954332_dt,
                                        1.3458238_dt,  2.1491122_dt, 0.33088169_dt, 0.26655897_dt, 0.55117583_dt, 1.1063218_dt,  2.029714_dt,   1.7879496_dt, 1.7211943_dt,  2.2004976_dt,
                                        2.404417_dt,   1.2298425_dt, 0.79554075_dt, 1.485776_dt,   3.175342_dt,   3.9317822_dt,  4.4431424_dt,  3.0550385_dt, 3.7402368_dt,  3.945177_dt,
                                        1.2426529_dt,  1.664371_dt,  1.8426224_dt,  1.3487302_dt,  3.1876945_dt,  2.3326287_dt,  3.1322505_dt,  3.905685_dt,  3.9447882_dt,  2.8370028_dt,
                                        3.2555163_dt,  3.1472173_dt, 5.619875_dt,   7.0883136_dt,  7.5981_dt,     5.300009_dt,   7.350748_dt,   7.4326067_dt, 2.5977278_dt,  3.4125273_dt,
                                        3.525877_dt,   2.4798262_dt, 3.449635_dt,   3.6449788_dt,  1.3442022_dt,  3.2291903_dt,  2.3998146_dt,  3.0021935_dt, 2.8047822_dt,  3.557187_dt,
                                        4.266777_dt,   5.831498_dt,  5.566462_dt,   3.9503753_dt,  4.689049_dt,   4.895632_dt,   2.3132772_dt,  2.7165463_dt, 2.5393875_dt,  1.1880282_dt,
                                        1.775405_dt,   1.4924512_dt, 0.5542402_dt,  2.064834_dt,   1.5583493_dt,  2.1136653_dt,  1.7646335_dt,  2.4166102_dt, 1.4375653_dt,  3.605618_dt,
                                        2.8356533_dt,  2.0830863_dt, 2.243164_dt,   2.9306808_dt,  0.9869584_dt,  1.3731908_dt,  1.4258399_dt,  0.6594024_dt, 0.69788325_dt, 0.9406414_dt };

    MANAGERS_DEFINE
    NETWORK_PARAMS_DEFINE(networkParameters);

    work.add<raul::DataLayer>("data_input", raul::DataParams{ { "input" }, 7u, 4u, 2u });
    work.add<raul::TensorLayer>("data_filters", raul::TensorParams{ { "filters" }, 5u, 3u, 2u, 3u });

    raul::DynamicDepthwiseConvolution2DLayer conv("conv2d", raul::BasicParams{ { "input", "filters" }, { "features" } }, networkParameters);

    TENSORS_CREATE(5u);
    memory_manager["input"] = TORANGE(input);
    memory_manager["filters"] = TORANGE(filters);
    memory_manager[raul::Name("features").grad()] = TORANGE(deltas);

    conv.forwardCompute(raul::NetworkMode::Train);

    // Forward checks
    const auto& features = memory_manager["features"];
    EXPECT_EQ(features.getBatchSize(), 5u);
    EXPECT_EQ(features.getDepth(), 3u);
    EXPECT_EQ(features.getHeight(), 2u);
    EXPECT_EQ(features.getWidth(), 6u);
    for (size_t i = 0; i < features.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(features[i], realFeatures[i], eps));
    }

    conv.backwardComputeImpl();

    // Backward checks
    const auto& inputGrad = memory_manager[raul::Name("input").grad()];
    for (size_t i = 0; i < inputGrad.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(inputGrad[i], realInputGrad[i], eps));
    }

    const auto& filtersGrad = memory_manager[raul::Name("filters").grad()];
    for (size_t i = 0; i < filtersGrad.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(filtersGrad[i], realFiltersGrad[i], eps));
    }
}

TEST(TestLayerDynamicDepthwiseConvolution2D, NonBatchedUnit)
{
    PROFILE_TEST

    // see tf_depthwise_conv2d.py
    // Test settings
    constexpr raul::dtype eps = 1.0e-6_dt;

    // Inputs
    const raul::Tensor input{
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0.01021147_dt, 0.1765188_dt,  0.87924564_dt, 0.9197762_dt,  0.5962018_dt,  0.47564948_dt,
        0.5654975_dt,  0.34476447_dt, 0.85968804_dt, 0.9875555_dt,  0.01058149_dt, 0.339782_dt,   0.2425921_dt,  0.9211738_dt,  0.1642909_dt,  0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0.5010754_dt,  0.06802893_dt, 0.92733943_dt,
        0.38135028_dt, 0.79155624_dt, 0.02508831_dt, 0.8701066_dt,  0.82625425_dt, 0.7514365_dt,  0.9443294_dt,  0.51774037_dt, 0.33772874_dt, 0.03504014_dt, 0.2998674_dt,  0.6926192_dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0.81010747_dt, 0.14049459_dt, 0.5186857_dt,  0.94181883_dt, 0.876843_dt,   0.30339718_dt, 0.40794075_dt, 0.55919313_dt, 0.3231908_dt,  0.17547584_dt, 0.9436065_dt,  0.7587601_dt,
        0.91779304_dt, 0.16914761_dt, 0.40076125_dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0.5133803_dt,  0.42446828_dt, 0.5984447_dt,  0.6057581_dt,  0.56168854_dt, 0.12310338_dt, 0.21958232_dt, 0.38766956_dt, 0.69197893_dt,
        0.40024364_dt, 0.09241581_dt, 0.6181046_dt,  0.43550146_dt, 0.47900355_dt, 0.09884691_dt, 0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,
        0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt,         0._dt
    };

    const raul::Tensor filters{ 0.72825086_dt, 0.09089839_dt, 0.5703032_dt,  0.5246129_dt,  0.02513623_dt, 0.8086195_dt,  0.31067622_dt, 0.41581333_dt, 0.39445984_dt, 0.818167_dt,   0.37038922_dt,
                                0.44542086_dt, 0.09213388_dt, 0.32764196_dt, 0.08026743_dt, 0.33068836_dt, 0.6397383_dt,  0.6067544_dt,  0.4225545_dt,  0.13956106_dt, 0.7970207_dt,  0.81368256_dt,
                                0.5407566_dt,  0.202963_dt,   0.735265_dt,   0.67287743_dt, 0.70911014_dt, 0.73380566_dt, 0.31025946_dt, 0.6905507_dt,  0.63429415_dt, 0.555498_dt,   0.59422433_dt,
                                0.23926544_dt, 0.0207057_dt,  0.06849682_dt, 0.05877316_dt, 0.04263389_dt, 0.5698596_dt,  0.11631501_dt, 0.93821836_dt, 0.7392818_dt,  0.1456263_dt,  0.7058301_dt,
                                0.6448051_dt,  0.37258422_dt, 0.32680643_dt, 0.7298577_dt,  0.59354806_dt, 0.88705945_dt, 0.6850368_dt,  0.85964084_dt, 0.10746598_dt, 0.18292606_dt, 0.34517407_dt,
                                0.7990773_dt,  0.38956988_dt, 0.01598418_dt, 0.64771616_dt, 0.866467_dt,   0.707366_dt,   0.8152659_dt,  0.94780564_dt, 0.56207216_dt, 0.2276349_dt,  0.16288865_dt,
                                0.46146047_dt, 0.68838036_dt, 0.9376774_dt,  0.12843692_dt, 0.7948899_dt,  0.45111728_dt, 0.24555266_dt, 0.43258548_dt, 0.42977738_dt, 0.85790086_dt, 0.28016567_dt,
                                0.6703578_dt,  0.3804351_dt,  0.12822366_dt, 0.19434083_dt, 0.85616803_dt, 0.34747386_dt, 0.4888357_dt,  0.9132589_dt,  0.4949168_dt,  0.37212765_dt, 0.6721473_dt,
                                0.629706_dt,   0.8874141_dt,  0.27165258_dt, 0.11999154_dt, 0.06307685_dt, 0.6719115_dt,  0.05676365_dt, 0.80641127_dt, 0.4519614_dt,  0.11959243_dt, 0.36097383_dt,
                                0.49697495_dt, 0.7626773_dt,  0.6142422_dt,  0.50659907_dt, 0.36766732_dt, 0.55378807_dt, 0.16661847_dt, 0.7330595_dt,  0.5390216_dt,  0.20473635_dt, 0.5092616_dt,
                                0.95956874_dt, 0.3083793_dt,  0.40405488_dt, 0.29207802_dt, 0.5329044_dt,  0.5597873_dt,  0.3113656_dt,  0.30077517_dt, 0.68057406_dt, 0.29917705_dt, 0.6745639_dt,
                                0.91068506_dt, 0.77012074_dt, 0.7781373_dt,  0.5271839_dt,  0.42010713_dt };

    const raul::Tensor realFeatures{ 1.1677732_dt,  1.1327978_dt,  1.219373_dt,   1.0997884_dt,  1.0406114_dt, 1.245983_dt,   1.2498852_dt,  1.6056075_dt,  1.1406971_dt,  1.1799679_dt,  1.5134155_dt,
                                     1.5352222_dt,  1.2388445_dt,  1.9898169_dt,  1.0857755_dt,  1.1466899_dt, 0.91438776_dt, 0.97642016_dt, 1.5531234_dt,  2.2470958_dt,  1.5303433_dt,  0.7080586_dt,
                                     1.1032326_dt,  1.6030853_dt,  0.9826737_dt,  2.1381812_dt,  1.5984172_dt, 1.0569761_dt,  1.3302375_dt,  1.4755971_dt,  1.1353354_dt,  1.1858466_dt,  1.3740151_dt,
                                     1.4935743_dt,  0.99506235_dt, 1.4458361_dt,  1.0894454_dt,  1.7232603_dt, 1.832293_dt,   1.2530274_dt,  1.5389601_dt,  1.7115577_dt,  1.4889032_dt,  2.123796_dt,
                                     1.7524469_dt,  0.85930073_dt, 0.749466_dt,   0.9304311_dt,  1.2838138_dt, 2.1812375_dt,  1.6798903_dt,  1.048529_dt,   1.419909_dt,   1.6999748_dt,  0.9521787_dt,
                                     1.8455267_dt,  1.601093_dt,   1.1899389_dt,  1.3354164_dt,  1.246784_dt,  2.0127654_dt,  1.9619832_dt,  1.4420117_dt,  1.5928972_dt,  0.96579635_dt, 1.1645594_dt,
                                     1.5263364_dt,  1.8895807_dt,  1.848565_dt,   1.5212554_dt,  1.0137587_dt, 1.3491881_dt,  1.4008342_dt,  2.3215978_dt,  1.9253362_dt,  0.71540314_dt, 1.0412362_dt,
                                     1.021352_dt,   1.3654492_dt,  2.5080738_dt,  1.9620675_dt,  1.3671541_dt, 0.90273196_dt, 1.0184839_dt,  1.136684_dt,   1.949634_dt,   1.5564426_dt,  0.9339007_dt,
                                     1.2032131_dt,  1.3867317_dt,  1.2465925_dt,  1.1973791_dt,  1.2918184_dt, 1.0443897_dt,  0.704969_dt,   1.0067571_dt,  0.97098774_dt, 1.2842218_dt,  1.1940488_dt,
                                     0.86167645_dt, 1.1732104_dt,  1.3134195_dt,  0.96076804_dt, 1.5823758_dt, 1.1695498_dt,  1.0145738_dt,  0.8205857_dt,  0.67395204_dt, 0.9941878_dt,  1.7012615_dt,
                                     1.3462441_dt,  0.7606633_dt,  0.87628555_dt, 1.204149_dt,   0.6949326_dt, 1.3191073_dt,  1.3596395_dt,  0.86261666_dt, 1.0989243_dt,  1.2105163_dt };

    const raul::Tensor deltas{ 0.13313437_dt, 0.11416864_dt, 0.83263075_dt, 0.26782572_dt, 0.04344749_dt, 0.19939256_dt, 0.9605675_dt,  0.6210573_dt,  0.79436934_dt, 0.50629103_dt, 0.6402621_dt,
                               0.54030013_dt, 0.562127_dt,   0.19475496_dt, 0.45741856_dt, 0.89240277_dt, 0.63750327_dt, 0.45551407_dt, 0.04760432_dt, 0.31664217_dt, 0.8744447_dt,  0.33307338_dt,
                               0.34883022_dt, 0.6697351_dt,  0.56559145_dt, 0.10826266_dt, 0.3126694_dt,  0.45361698_dt, 0.60872674_dt, 0.9392239_dt,  0.4712106_dt,  0.40582657_dt, 0.74381626_dt,
                               0.6904721_dt,  0.51705444_dt, 0.56366825_dt, 0.48726392_dt, 0.6419326_dt,  0.23007059_dt, 0.7204796_dt,  0.7305455_dt,  0.8685031_dt,  0.4747963_dt,  0.4136318_dt,
                               0.58509445_dt, 0.36083388_dt, 0.75604653_dt, 0.4816519_dt,  0.37079167_dt, 0.20339346_dt, 0.06977868_dt, 0.87573063_dt, 0.18314803_dt, 0.6457157_dt,  0.6279726_dt,
                               0.34137547_dt, 0.97568464_dt, 0.5323595_dt,  0.55254424_dt, 0.26628053_dt, 0.05504179_dt, 0.9998379_dt,  0.03265238_dt, 0.14103556_dt, 0.9608103_dt,  0.397375_dt,
                               0.2576326_dt,  0.4989009_dt,  0.27725708_dt, 0.70624924_dt, 0.6668159_dt,  0.7953532_dt,  0.16207945_dt, 0.08067286_dt, 0.58791435_dt, 0.28615236_dt, 0.31968975_dt,
                               0.07930934_dt, 0.70950806_dt, 0.4748652_dt,  0.40453756_dt, 0.6115334_dt,  0.2513436_dt,  0.90194166_dt, 0.958609_dt,   0.37559354_dt, 0.7585801_dt,  0.16757655_dt,
                               0.02005875_dt, 0.12391651_dt, 0.65940046_dt, 0.7076644_dt,  0.5556011_dt,  0.9214721_dt,  0.6244832_dt,  0.07338941_dt, 0.26348615_dt, 0.4965471_dt,  0.40726805_dt,
                               0.8692074_dt,  0.14704847_dt, 0.5777532_dt,  0.38797998_dt, 0.09531462_dt, 0.55477977_dt, 0.41230667_dt, 0.6197858_dt,  0.87575734_dt, 0.5060594_dt,  0.75868726_dt,
                               0.27394187_dt, 0.3676635_dt,  0.10253441_dt, 0.49808252_dt, 0.9871435_dt,  0.09287333_dt, 0.256451_dt,   0.70734787_dt, 0.9495864_dt,  0.3149048_dt };

    const raul::Tensor realInputGrad{
        0.10733296_dt, 0.6153568_dt,  0.16232482_dt, 0.84482175_dt, 1.2662038_dt, 0.5578971_dt,  1.0334144_dt,  1.6120107_dt,  1.0109465_dt,  0.6832466_dt, 2.6967363_dt,  1.7907424_dt,  1.3510659_dt,
        3.1976035_dt,  2.4935708_dt,  1.8656075_dt,  3.259173_dt,   2.2968366_dt, 1.6632171_dt,  3.2210863_dt,  2.0346513_dt,  1.1498107_dt,  3.1163638_dt, 2.2947826_dt,  1.4946784_dt,  3.0198233_dt,
        2.47014_dt,    1.9127548_dt,  2.7668734_dt,  1.8086905_dt,  1.789782_dt,  3.2566433_dt,  2.9453454_dt,  2.1433992_dt,  3.3010502_dt,  2.2102842_dt, 2.2104678_dt,  3.28276_dt,    2.1613019_dt,
        1.5368422_dt,  2.8554683_dt,  2.7629628_dt,  1.5737187_dt,  3.4539347_dt, 2.0458262_dt,  1.9574974_dt,  2.7343302_dt,  2.944356_dt,   1.2634692_dt, 2.5726376_dt,  2.6820889_dt,  1.2231464_dt,
        2.6709704_dt,  2.8476694_dt,  1.6987537_dt,  2.7146494_dt,  3.3790646_dt, 1.2301981_dt,  2.4658866_dt,  2.6879723_dt,  1.676707_dt,   2.8414285_dt, 2.752582_dt,   2.1194658_dt,  2.6070976_dt,
        2.4237237_dt,  0.93010294_dt, 1.8590455_dt,  1.4855059_dt,  0.6824837_dt, 1.166396_dt,   1.160536_dt,   0.48012075_dt, 0.5937695_dt,  0.7154856_dt, 0.3800485_dt,  0.78643143_dt, 0.46878994_dt,
        0.728343_dt,   1.3675101_dt,  1.1632327_dt,  0.978055_dt,   1.4912409_dt, 1.7387006_dt,  1.1189864_dt,  2.4366167_dt,  2.4096417_dt,  1.7824104_dt, 3.549758_dt,   2.48156_dt,    2.0107336_dt,
        3.174596_dt,   2.2145352_dt,  1.692854_dt,   2.5155034_dt,  2.288757_dt,  1.6644881_dt,  3.2887077_dt,  2.8120599_dt,  2.248878_dt,   3.2287943_dt, 2.5000532_dt,  2.3250968_dt,  2.4382539_dt,
        2.3381824_dt,  2.2430701_dt,  2.894434_dt,   2.850984_dt,   2.5921462_dt, 3.2709584_dt,  2.3928103_dt,  2.59715_dt,    3.14487_dt,    2.5319872_dt, 2.0501275_dt,  2.9946346_dt,  2.795827_dt,
        2.2280254_dt,  3.365367_dt,   2.644926_dt,   1.8768839_dt,  3.2679114_dt, 3.2563124_dt,  1.5782375_dt,  3.2098918_dt,  3.0985208_dt,  1.5854976_dt, 2.5074172_dt,  3.215337_dt,   1.9176538_dt,
        2.8783731_dt,  3.3650494_dt,  1.7010297_dt,  2.146011_dt,   2.6656342_dt, 2.2015767_dt,  2.8724823_dt,  2.7798615_dt,  2.0209937_dt,  1.9945602_dt, 2.219821_dt,   1.3108406_dt,  2.1169014_dt,
        1.219783_dt,   0.961097_dt,   1.1990918_dt,  0.8235348_dt,  0.7344932_dt, 1.1656438_dt,  0.40315878_dt, 0.13096789_dt, 0.09261083_dt, 0.3454763_dt, 0.66581655_dt, 0.65689874_dt, 1.1927723_dt,
        0.74551755_dt, 1.221865_dt,   1.5291914_dt,  0.9937576_dt,  1.4141424_dt, 2.3987699_dt,  2.0832257_dt,  2.2445505_dt,  1.9427035_dt,  1.8701437_dt, 2.1404536_dt,  1.7628777_dt,  1.2373285_dt,
        1.9319458_dt,  1.8244576_dt,  2.196448_dt,   2.2081327_dt,  2.5665026_dt, 2.9935918_dt,  2.0014248_dt,  1.4917082_dt,  2.37259_dt,    2.0902548_dt, 2.2576642_dt,  2.020271_dt,   1.8187227_dt,
        2.3042188_dt,  2.67012_dt,    2.296483_dt,   1.7891291_dt,  2.6152835_dt, 2.034862_dt,   2.4792285_dt,  2.0785878_dt,  2.4655206_dt,  1.8624862_dt, 2.4203782_dt,  2.5347066_dt,  2.3523166_dt,
        1.7696817_dt,  2.4652743_dt,  2.3974323_dt,  1.1909232_dt,  2.0569973_dt, 2.5447206_dt,  1.9211378_dt,  1.574482_dt,   3.0239453_dt,  2.228361_dt,  1.5318108_dt,  2.5785477_dt,  1.6905537_dt,
        1.5200746_dt,  2.3983955_dt,  2.4507065_dt,  1.7690592_dt,  2.2793984_dt, 1.7704803_dt,  2.056984_dt,   1.37346_dt,    1.2142613_dt,  1.7649109_dt, 0.68705_dt,    1.6321607_dt,  1.0739983_dt,
        0.5621409_dt,  0.9886904_dt,  0.7145958_dt,  0.06263286_dt, 0.5445345_dt, 0.80027723_dt, 0.07504126_dt, 0.73613566_dt, 1.661344_dt,   0.7348698_dt, 0.8721541_dt,  1.7538185_dt,  1.4795772_dt,
        1.1620317_dt,  2.4180233_dt,  1.8221947_dt,  2.4086394_dt,  3.2091076_dt, 1.9074223_dt,  2.1569552_dt,  3.078372_dt,   1.8352387_dt,  1.3023868_dt, 2.3417234_dt,  2.4349203_dt,  2.2438877_dt,
        2.7070842_dt,  1.8487272_dt,  2.9655852_dt,  3.0749679_dt,  2.3275113_dt, 2.2535396_dt,  2.2892246_dt,  1.9369491_dt,  2.5171118_dt,  2.4936097_dt, 2.497524_dt,   2.775391_dt,   2.669236_dt,
        2.4596434_dt,  2.7328248_dt,  3.1767502_dt,  1.5430514_dt,  2.2571979_dt, 2.968308_dt,   2.5614862_dt,  2.782628_dt,   3.1863427_dt,  2.1262536_dt, 1.8821661_dt,  2.6152751_dt,  2.6028903_dt,
        1.4876878_dt,  2.8368764_dt,  2.919303_dt,   2.1146412_dt,  2.3567472_dt, 2.6962397_dt,  2.1741772_dt,  2.4280248_dt,  2.988492_dt,   1.8847075_dt, 2.2579832_dt,  2.293509_dt,   2.6281857_dt,
        2.8497248_dt,  2.4004908_dt,  1.9142599_dt,  1.9228818_dt,  2.0568087_dt, 1.2923046_dt,  1.4081726_dt,  1.3891119_dt,  1.610337_dt,   0.7896637_dt, 1.0037787_dt,  0.7504697_dt,  0.74791205_dt,
        0.6329004_dt
    };

    const raul::Tensor realFiltersGrad{ 0._dt,         0._dt,        0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        1.6037935_dt, 0.52411085_dt, 0.33699852_dt, 0.4400781_dt, 1.6262956_dt,  1.3254677_dt, 3.2813606_dt, 1.5190967_dt,
                                        2.1001425_dt,  1.5964346_dt, 1.0946635_dt, 2.4833422_dt, 3.208155_dt,   2.1310265_dt,  2.9613686_dt, 2.9959674_dt,  3.6598485_dt, 3.3476024_dt, 4.1486936_dt,
                                        2.7063766_dt,  3.870176_dt,  3.7335548_dt, 3.7550666_dt, 4.7942333_dt,  5.1676087_dt,  4.8035135_dt, 4.0347257_dt,  5.4231215_dt, 4.6004987_dt, 4.781832_dt,
                                        3.966888_dt,   4.3378425_dt, 4.14267_dt,   4.202571_dt,  3.2113044_dt,  3.899431_dt,   2.682681_dt,  2.6640391_dt,  2.5240722_dt, 3.4002225_dt, 3.0474308_dt,
                                        2.7384732_dt,  1.4513367_dt, 1.8019592_dt, 1.5187945_dt, 1.7968041_dt,  2.1973555_dt,  1.6711557_dt, 0.38649547_dt, 1.2677498_dt, 1.2617018_dt, 0.9190084_dt,
                                        0.81204367_dt, 0.5896726_dt, 0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        0._dt,        0._dt,         0._dt,         0._dt,        0._dt,         0._dt,        0._dt,        0._dt,
                                        0._dt,         0._dt,        0._dt,        0._dt,        0._dt };

    MANAGERS_DEFINE
    NETWORK_PARAMS_DEFINE(networkParameters);

    work.add<raul::TensorLayer>("data_input", raul::TensorParams{ { "input" }, 1u, 4u, 25u, 3u });
    work.add<raul::TensorLayer>("data_filters", raul::TensorParams{ { "filters" }, 1u, 21u, 3u, 2u });

    raul::DynamicDepthwiseConvolution2DLayer conv("conv2d", raul::BasicParams{ { "input", "filters" }, { "features" } }, networkParameters);
    TENSORS_CREATE(5u);
    memory_manager["input"] = TORANGE(input);
    memory_manager["filters"] = TORANGE(filters);
    memory_manager[raul::Name("features").grad()] = TORANGE(deltas);

    conv.forwardCompute(raul::NetworkMode::Train);

    // Forward checks
    const auto& features = memory_manager["features"];
    EXPECT_EQ(features.getBatchSize(), 1u);
    EXPECT_EQ(features.getDepth(), 4u);
    EXPECT_EQ(features.getHeight(), 5u);
    EXPECT_EQ(features.getWidth(), 6u);
    for (size_t i = 0; i < features.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(features[i], realFeatures[i], eps));
    }

    conv.backwardComputeImpl();

    // Backward checks
    const auto& inputGrad = memory_manager[raul::Name("input").grad()];
    for (size_t i = 0; i < inputGrad.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(inputGrad[i], realInputGrad[i], eps));
    }

    const auto& filtersGrad = memory_manager[raul::Name("filters").grad()];
    for (size_t i = 0; i < filtersGrad.size(); ++i)
    {
        ASSERT_TRUE(tools::expect_near_relative(filtersGrad[i], realFiltersGrad[i], eps));
    }
}

}